package com.eastfair.visitor.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.venuebooking.entity.PriceList;
import com.eastfair.venueservice.entity.EvaluateComplaint;
import com.eastfair.visitor.dao.ReservationAuditRecordMapper;
import com.eastfair.visitor.dao.ReservationMapper;
import com.eastfair.visitor.entity.AuditSettings;
import com.eastfair.visitor.entity.Department;
import com.eastfair.visitor.entity.Reservation;
import com.eastfair.visitor.entity.ReservationAuditRecord;
import com.eastfair.visitor.service.AuditSettingsService;
import com.eastfair.visitor.service.ReservationAuditRecordService;
import com.eastfair.boot.service.SuperServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;

import java.util.Collection;

//import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.aop.framework.AopContext;
import com.eastfair.annotation.annotation.cache.Magic;
import com.eastfair.annotation.annotation.cache.Cache;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
//import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.eastfair.visitor.vo.*;
import com.eastfair.visitor.dto.*;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 业务实现类
 * 访客预约审核记录
 * </p>
 *
 * @author lyw
 * @date 2022-11-18
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ReservationAuditRecordServiceImpl extends SuperServiceImpl<ReservationAuditRecordMapper, ReservationAuditRecord> implements ReservationAuditRecordService {

    @Autowired
    private ReservationAuditRecordMapper reservationAuditRecordMapper;
    @Autowired
    private ReservationMapper reservationMapper;
    @Autowired
    private AuditSettingsService auditSettingsService;

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ReservationAuditRecord> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    /**
     * 通用查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    public List<ReservationAuditRecord> list(ReservationAuditRecordDTO modelDTO, List<Long> ids) {
        return ((ReservationAuditRecordService) AopContext.currentProxy()).listOfCache(modelDTO, ids);
    }

    @Override
    protected R<Boolean> handlerSave(ReservationAuditRecord model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }


    /**
     * 缓存查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    @Cache(key = "",
            magic = @Magic(
                    key = "{" +
                            "{'visitorId', #args[0]?.visitorId}," +
                            "{'visitorName', #args[0]?.visitorName}," +
                            "{'idcard', #args[0]?.idcard}," +
                            "{'mobilePhone', #args[0]?.mobilePhone}," +
                            "{'departmentId', #args[0]?.departmentId}," +
                            "{'admissionTime', #args[0]?.admissionTime}," +
                            "{'outTime', #args[0]?.outTime}," +
                            "{'trip', #args[0]?.trip}," +
                            "{'isRisk', #args[0]?.isRisk}," +
                            "{'isExit', #args[0]?.isExit}," +
                            "{'isEnabled', #args[0]?.isEnabled}," +
                            "{'auditStatus', #args[0]?.auditStatus}," +
                            "{'id', #args[1]}" +
                            "}"))
    public List<ReservationAuditRecord> listOfCache(ReservationAuditRecordDTO modelDTO, List<Long> ids) {
        //查询
        QueryWrapper<ReservationAuditRecord> queryWrapper = new QueryWrapper<>();
        if (modelDTO != null) {
            queryWrapper.lambda().eq(modelDTO.getVisitorId() != null, ReservationAuditRecord::getVisitorId, modelDTO.getVisitorId());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getVisitorName()), ReservationAuditRecord::getVisitorName, modelDTO.getVisitorName());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getIdcard()), ReservationAuditRecord::getIdcard, modelDTO.getIdcard());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getMobilePhone()), ReservationAuditRecord::getMobilePhone, modelDTO.getMobilePhone());
            queryWrapper.lambda().eq(modelDTO.getDepartmentId() != null, ReservationAuditRecord::getDepartmentId, modelDTO.getDepartmentId());
            queryWrapper.lambda().eq(modelDTO.getAdmissionTime() != null, ReservationAuditRecord::getAdmissionTime, modelDTO.getAdmissionTime());
            queryWrapper.lambda().eq(modelDTO.getOutTime() != null, ReservationAuditRecord::getOutTime, modelDTO.getOutTime());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getTrip()), ReservationAuditRecord::getTrip, modelDTO.getTrip());
            queryWrapper.lambda().eq(modelDTO.getIsRisk() != null, ReservationAuditRecord::getIsRisk, modelDTO.getIsRisk());
            queryWrapper.lambda().eq(modelDTO.getIsExit() != null, ReservationAuditRecord::getIsExit, modelDTO.getIsExit());
            queryWrapper.lambda().eq(modelDTO.getAuditStatus() != null, ReservationAuditRecord::getAuditStatus, modelDTO.getAuditStatus());
        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(ReservationAuditRecord::getId, ids);
        }
        queryWrapper.lambda().eq(ReservationAuditRecord::getIsDeleted, BusinessConstant.DELETE_NO);
        List<ReservationAuditRecord> modelList = list(queryWrapper);
        return modelList;
    }

    /**
     * 查询访客列表分页
     *
     * @param params
     * @return
     */
    @Override
    public IPage<ReservationAuditRecordVO> queryReservationList(PageParams<ReservationAuditRecordPageQuery> params) {
        log.info("ReservationAuditRecordServiceImpl +++++ queryReservationList - 查询访客列表分页 params={}", JSONObject.toJSON(params));
        handlerQueryParams(params);
        Page<ReservationAuditRecord> page = params.buildPage();
        ReservationAuditRecordPageQuery model = params.getModel();
        QueryWrapper<ReservationAuditRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ReservationAuditRecord::getIsDeleted, BusinessConstant.DELETE_NO)
                .eq(Objects.nonNull(model.getIsDeleted()),ReservationAuditRecord::getIsDeleted,model.getIsDeleted())
                .eq(StringUtils.isNotBlank(model.getMobilePhone()), ReservationAuditRecord::getMobilePhone, model.getMobilePhone())
                .eq(Objects.nonNull(model.getDepartmentId()),ReservationAuditRecord::getDepartmentId,model.getDepartmentId())
                .eq(Objects.nonNull(model.getUserId()),ReservationAuditRecord::getUserId,model.getUserId())
                .like(StringUtils.isNotBlank(model.getVisitorName()),ReservationAuditRecord::getVisitorName,model.getVisitorName())
                .like(StringUtils.isNotBlank(model.getCompanyName()),ReservationAuditRecord::getCompanyName,model.getCompanyName())
                .like(StringUtils.isNotBlank(model.getReceiver()),ReservationAuditRecord::getReceiver,model.getReceiver())
                .eq(Objects.nonNull(model.getAuditStatus()),ReservationAuditRecord::getAuditStatus,model.getAuditStatus())
                .eq(Objects.nonNull(model.getAboutStatus()), ReservationAuditRecord::getAboutStatus, model.getAboutStatus())
                .between(Objects.nonNull(model.getAdmissionCreateBeginTime())
                                && Objects.nonNull(model.getAdmissionCreateEndTime()),
                        ReservationAuditRecord::getAdmissionTime,model.getAdmissionCreateBeginTime() , model.getAdmissionCreateEndTime())
                .between(Objects.nonNull(model.getOutCreateBeginTime())
                                && Objects.nonNull(model.getOutCreateEndTime()),
                        ReservationAuditRecord::getOutTime,model.getOutCreateBeginTime() , model.getAdmissionCreateEndTime())
                .orderByDesc(ReservationAuditRecord::getCreateTime);
        page = page(page, queryWrapper);
        List<ReservationAuditRecord> records = page.getRecords();
        Page<ReservationAuditRecordVO> resultPage = ConvertUtil.convertPage(page, ReservationAuditRecordVO.class);
        return resultPage;
    }


    /**
     * 取消访客预约
     * @param reservationAuditRecordUpdateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delReservationInfo(ReservationAuditRecordUpdateDTO reservationAuditRecordUpdateDTO) {
        log.info("ReservationAuditRecordServiceImpl +++++ delReservationInfo - 取消访客预约 reservationAuditRecordUpdateDTO={}", JSONObject.toJSON(reservationAuditRecordUpdateDTO));
        ReservationAuditRecord reservationAuditRecord = BeanUtil.toBean(reservationAuditRecordUpdateDTO, ReservationAuditRecord.class);
        reservationAuditRecord.setAboutStatus(BusinessConstant.YES);
        reservationAuditRecordMapper.updateById(reservationAuditRecord);
        return Boolean.TRUE;
    }

    /**
     * 添加访客预约信息
     * @param reservationAuditRecordSaveDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveReservationInfo(ReservationAuditRecordSaveDTO reservationAuditRecordSaveDTO) {
        log.info("ReservationAuditRecordServiceImpl +++++ saveReservationInfo - 添加访客预约信息 reservationAuditRecordSaveDTO={}", JSONObject.toJSON(reservationAuditRecordSaveDTO));
        ReservationAuditRecord reservationAuditRecord = BeanUtil.toBean(reservationAuditRecordSaveDTO, ReservationAuditRecord.class);
        //判断审核开关是否开启
        AuditSettingsVO auditSettingsInfo = auditSettingsService.getAuditSettingsInfo();
        if(Objects.nonNull(auditSettingsInfo) && auditSettingsInfo.getIsEnabled()==BusinessConstant.DELETE_NO){
            reservationAuditRecord.setAuditStatus(BusinessConstant.YES);
        }else {
            reservationAuditRecord.setAuditStatus(BusinessConstant.DELETE_NO);
        }
        boolean save = save(reservationAuditRecord);
        return save;
    }

    /**
     * 修改访客审核状态
     * @param reservationAuditRecordUpdateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAuditStatusById(ReservationAuditRecordUpdateDTO reservationAuditRecordUpdateDTO) {
        log.info("ReservationAuditRecordServiceImpl +++++ updateAuditStatusById - 修改访客审核状态 reservationAuditRecordUpdateDTO={}", JSONObject.toJSON(reservationAuditRecordUpdateDTO));
        ReservationAuditRecord reservationAuditRecord = BeanUtil.toBean(reservationAuditRecordUpdateDTO, ReservationAuditRecord.class);
        reservationAuditRecordMapper.updateById(reservationAuditRecord);
        return Boolean.TRUE;
    }

    /**
     * 通过id查询访客信息
     * @param reservationAuditRecordDTO
     * @return
     */
    @Override
    public ReservationAuditRecordVO getReservationInfoById(ReservationAuditRecordDTO reservationAuditRecordDTO) {
        log.info("ReservationAuditRecordServiceImpl +++++ getReservationInfoById - 通过id获取访客信息 reservationAuditRecordDTO={}", JSONObject.toJSON(reservationAuditRecordDTO));
        ReservationAuditRecord reservationAuditRecord = reservationAuditRecordMapper.selectById(reservationAuditRecordDTO.getId());
        ReservationAuditRecordVO reservationAuditRecordVO = BeanUtil.toBean(reservationAuditRecord, ReservationAuditRecordVO.class);
        return reservationAuditRecordVO;
    }

    /**
     * 删除访客预约记录
     * @param reservationAuditRecordUpdateDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delAuditStatusById(ReservationAuditRecordUpdateDTO reservationAuditRecordUpdateDTO) {
        log.info("ReservationAuditRecordServiceImpl +++++ delAuditStatusById - 删除访客预约记录 reservationAuditRecordUpdateDTO={}", JSONObject.toJSON(reservationAuditRecordUpdateDTO));
        ReservationAuditRecord reservationAuditRecord = BeanUtil.toBean(reservationAuditRecordUpdateDTO, ReservationAuditRecord.class);
        reservationAuditRecord.setIsDeleted(BusinessConstant.YES);
        reservationAuditRecordMapper.updateById(reservationAuditRecord);
        return null;
    }


    /**
     * do转vo
     *
     * @param model model
     * @return modelVo
     */
    @Override
    public ReservationAuditRecordVO doToVo(ReservationAuditRecord model) {
        ReservationAuditRecordVO modelVo = new ReservationAuditRecordVO();
        BeanUtils.copyProperties(model, modelVo);
        modelVo.setId(model.getId());
        return modelVo;
    }

    /**
     * do转vo
     *
     * @param modelList modelList
     * @return list
     */
    @Override
    public List<ReservationAuditRecordVO> doToVos(List<ReservationAuditRecord> modelList) {
        if (modelList == null || modelList.isEmpty()) {
            return null;
        }
        List<ReservationAuditRecordVO> result = new ArrayList<>();
        for (ReservationAuditRecord model : modelList) {
            result.add(doToVo(model));
        }
        return result;
    }

    public void handlerQueryParams(PageParams<ReservationAuditRecordPageQuery> params) {
        if (StrUtil.isBlank(params.getSort()) || StrUtil.isBlank(params.getOrder())) {
            params.setSort("createTime");
            params.setOrder("descending");
        }
    }
}
